#include "validate.h" // for ValidateFilter
#include "vecs.h" // for Vecs
+template <typename T>
+Filter* fltfactory()
+{
+ static_assert(std::is_base_of<Filter, T>::value, "T must be derived from Filter");
+ return new T();
+}
struct FilterVecs::Impl {
ArcDistanceFilter arcdist;
DuplicateFilter duplicate;
HeightFilter height;
InterpolateFilter interpolate;
- NukeDataFilter nukedata;
PolygonFilter polygon;
PositionFilter position;
RadiusFilter radius;
- ResampleFilter resample;
ReverseRouteFilter reverse_route;
SimplifyRouteFilter routesimple;
- SortFilter sort;
StackFilter stackfilt;
SwapDataFilter swapdata;
TrackFilter trackfilter;
- TransformFilter transform;
- ValidateFilter validate;
const QVector<fl_vecs_t> filter_vec_list = {
#if FILTERS_ENABLED
"Interpolate between trackpoints"
},
{
- &nukedata,
+ nullptr,
"nuketypes",
- "Remove all waypoints, tracks, or routes"
+ "Remove all waypoints, tracks, or routes",
+ &fltfactory<NukeDataFilter>
},
{
&polygon,
"Include Only Points Within Radius",
},
{
- &resample,
+ nullptr,
"resample",
"Resample Track",
+ &fltfactory<ResampleFilter>
},
{
&routesimple,
"Simplify routes",
},
{
- &sort,
+ nullptr,
"sort",
"Rearrange waypoints, routes and/or tracks by resorting",
+ &fltfactory<SortFilter>
},
{
&stackfilt,
"Manipulate track lists"
},
{
- &transform,
+ nullptr,
"transform",
- "Transform waypoints into a route, tracks into routes, ..."
+ "Transform waypoints into a route, tracks into routes, ...",
+ &fltfactory<TransformFilter>
},
{
&height,
"Swap latitude and longitude of all loaded points"
},
{
- &validate,
+ nullptr,
"validate",
- "Validate internal data structures"
+ "Validate internal data structures",
+ &fltfactory<ValidateFilter>
}
#elif defined (MINIMAL_FILTERS)
{
return instance;
}
-Filter* FilterVecs::find_filter_vec(const QString& vecname)
+void FilterVecs::prepare_filter(const fltinfo_t& fltdata)
{
- QStringList options = vecname.split(',');
- if (options.isEmpty()) {
- fatal("A filter name is required.\n");
- }
- const QString svecname = options.takeFirst();
+ QVector<arglist_t>* args = fltdata->get_args();
- for (const auto& vec : d_ptr_->filter_vec_list) {
- if (svecname.compare(vec.name, Qt::CaseInsensitive) != 0) {
- continue;
- }
+ Vecs::validate_options(fltdata.options, args, fltdata.fltname);
- QVector<arglist_t>* args = vec.vec->get_args();
-
- Vecs::validate_options(options, args, vec.name);
+ /* step 1: initialize by inifile or default values */
+ if (args && !args->isEmpty()) {
+ assert(args->isDetached());
+ for (auto& arg : *args) {
+ QString qtemp = inifile_readstr(global_opts.inifile, fltdata.fltname, arg.argstring);
+ if (qtemp.isNull()) {
+ qtemp = inifile_readstr(global_opts.inifile, "Common filter settings", arg.argstring);
+ }
+ if (qtemp.isNull()) {
+ Vecs::assign_option(fltdata.fltname, &arg, arg.defaultvalue);
+ } else {
+ Vecs::assign_option(fltdata.fltname, &arg, qtemp);
+ }
+ }
+ }
- /* step 1: initialize by inifile or default values */
+ /* step 2: override settings with command-line values */
+ if (!fltdata.options.isEmpty()) {
if (args && !args->isEmpty()) {
assert(args->isDetached());
for (auto& arg : *args) {
- QString qtemp = inifile_readstr(global_opts.inifile, vec.name, arg.argstring);
- if (qtemp.isNull()) {
- qtemp = inifile_readstr(global_opts.inifile, "Common filter settings", arg.argstring);
- }
- if (qtemp.isNull()) {
- Vecs::assign_option(vec.name, &arg, arg.defaultvalue);
- } else {
- Vecs::assign_option(vec.name, &arg, qtemp);
+ const QString opt = Vecs::get_option(fltdata.options, arg.argstring);
+ if (!opt.isNull()) {
+ Vecs::assign_option(fltdata.fltname, &arg, opt);
}
}
}
+ }
- /* step 2: override settings with command-line values */
- if (!options.isEmpty()) {
- if (args && !args->isEmpty()) {
- assert(args->isDetached());
- for (auto& arg : *args) {
- const QString opt = Vecs::get_option(options, arg.argstring);
- if (!opt.isNull()) {
- Vecs::assign_option(vec.name, &arg, opt);
- }
- }
- }
- }
+ if (global_opts.debug_level >= 1) {
+ Vecs::disp_vec_options(fltdata.fltname, args);
+ }
- if (global_opts.debug_level >= 1) {
- Vecs::disp_vec_options(vec.name, args);
- }
+}
+
+FilterVecs::fltinfo_t FilterVecs::find_filter_vec(const QString& fltargstring)
+{
+ QStringList options = fltargstring.split(',');
+ if (options.isEmpty()) {
+ fatal("A filter name is required.\n");
+ }
+ const QString fltname = options.takeFirst();
- return vec.vec;
+ for (const auto& vec : d_ptr_->filter_vec_list) {
+ if (fltname.compare(vec.name, Qt::CaseInsensitive) != 0) {
+ continue;
+ }
+ return {vec.vec, vec.name, options, vec.factory};
}
- return nullptr;
+
+ /*
+ * Not found.
+ */
+ return {};
}
-void FilterVecs::free_filter_vec(Filter* filter)
+void FilterVecs::free_filter_vec(fltinfo_t& filter)
{
QVector<arglist_t>* args = filter->get_args();
}
}
+void FilterVecs::init_filter_vec(Filter* flt)
+{
+ QVector<arglist_t>* args = flt->get_args();
+ if (args && !args->isEmpty()) {
+ assert(args->isDetached());
+ for (auto& arg : *args) {
+ arg.argvalptr = nullptr;
+ }
+ }
+}
+
void FilterVecs::init_filter_vecs()
{
for (const auto& vec : d_ptr_->filter_vec_list) {
- QVector<arglist_t>* args = vec.vec->get_args();
- if (args && !args->isEmpty()) {
- assert(args->isDetached());
- for (auto& arg : *args) {
- arg.argvalptr = nullptr;
- }
+ if (vec.vec != nullptr) {
+ init_filter_vec(vec.vec);
}
}
}
-void FilterVecs::exit_filter_vecs()
+void FilterVecs::exit_filter_vec(Filter* flt)
{
- for (const auto& vec : d_ptr_->filter_vec_list) {
- (vec.vec->exit)();
- QVector<arglist_t>* args = vec.vec->get_args();
+ (flt->exit)();
+ QVector<arglist_t>* args = flt->get_args();
if (args && !args->isEmpty()) {
assert(args->isDetached());
for (auto& arg : *args) {
}
}
}
+}
+
+void FilterVecs::exit_filter_vecs()
+{
+ for (const auto& vec : d_ptr_->filter_vec_list) {
+ if (vec.vec != nullptr) {
+ exit_filter_vec(vec.vec);
+ }
}
}
void FilterVecs::disp_filter_vecs() const
{
for (const auto& vec : d_ptr_->filter_vec_list) {
+ Filter* flt = (vec.factory != nullptr)? vec.factory() : vec.vec;
printf(" %-20.20s %-50.50s\n",
qPrintable(vec.name), qPrintable(vec.desc));
- const QVector<arglist_t>* args = vec.vec->get_args();
+ const QVector<arglist_t>* args = flt->get_args();
if (args) {
for (const auto& arg : *args) {
if (!(arg.argtype & ARGTYPE_HIDDEN)) {
}
}
}
+ if (vec.factory != nullptr) {
+ delete flt;
+ }
}
}
if (vecname.compare(vec.name, Qt::CaseInsensitive) != 0) {
continue;
}
+ Filter* flt = (vec.factory != nullptr)? vec.factory() : vec.vec;
printf(" %-20.20s %-50.50s\n",
qPrintable(vec.name), qPrintable(vec.desc));
- const QVector<arglist_t>* args = vec.vec->get_args();
+ const QVector<arglist_t>* args = flt->get_args();
if (args) {
for (const auto& arg : *args) {
if (!(arg.argtype & ARGTYPE_HIDDEN)) {
}
}
}
+ if (vec.factory != nullptr) {
+ delete flt;
+ }
}
}
void FilterVecs::disp_v1(const fl_vecs_t& vec)
{
+ Filter* flt = (vec.factory != nullptr)? vec.factory() : vec.vec;
disp_help_url(vec, nullptr);
printf("\n");
- const QVector<arglist_t>* args = vec.vec->get_args();
+ const QVector<arglist_t>* args = flt->get_args();
if (args) {
for (const auto& arg : *args) {
if (!(arg.argtype & ARGTYPE_HIDDEN)) {
}
}
}
+ if (vec.factory != nullptr) {
+ delete flt;
+ }
}
/*
bool FilterVecs::validate_filter_vec(const fl_vecs_t& vec)
{
- bool ok = Vecs::validate_args(vec.name, vec.vec->get_args());
+ Filter* flt = (vec.factory != nullptr)? vec.factory() : vec.vec;
+ bool ok = Vecs::validate_args(vec.name, flt->get_args());
+ if (vec.factory != nullptr) {
+ delete flt;
+ }
return ok;
}